package org.flashbrighton.as3bots.collision
{
	public class CollisionDetector
	{
		private var _collidableMap:Array;
		
		
		public function CollisionDetector():void
		{
			_collidableMap = new Array();
		}
		
		
		public function registerCollidable(collidable:Collidable):void
		{
			_collidableMap.push(collidable);
		}
		
		
		public function removeCollidable(collidable:Collidable):void
		{
			_collidableMap.splice(_collidableMap.indexOf(collidable), 1);
		}
		
		
		public function getFirstCollisionTime():SweepTestResults
		{
			var n:int = 0;
			var	results:Array = [];
			var	m:int;
			var	testResults:SweepTestResults;
			var	collidableA:Collidable;
			var	collidableB:Collidable;
			
			// this nested loop makes sure that everyitem is compared to every other one once only, 
			// and never with its self
			while(n < _collidableMap.length -1)
			{
				m = n+1;
				
				while(m < _collidableMap.length)
				{
					collidableA = _collidableMap[n];
					collidableB = _collidableMap[m];
					
					testResults = new SweepTestResults(collidableA, collidableB, collidableA.metrics.getCollisionTime(collidableB.metrics));
					
					// if there is a collision push onto results
					if (testResults.time != -1) results.push(testResults);
					
					m++;
				}
			
				n++;
			}
			
			// if there are no collisions
			if (results.length == 0)
			{
				testResults.numCollisions = 0;
				return testResults;
			}
			// if there is only one collision
			else if (results.length == 1)
			{
				results[0].numCollisions = 1;
				return results[0];
			}
			// if there are multiple collisions
			else
			{
				results.sort(numericSort);
				results[0].numCollisions = results.length;
				return results[0];
			}
			
		}
		
		
		// sorts the results by time, smallest first
		private function numericSort(a:SweepTestResults, b:SweepTestResults):int
		{
			if (a.time == b.time)
			{
				return 0;
			}
			else if (a.time < b.time)
			{
				return -1;
			}
			
			return 1;
		}
		
	}
}

